package com.jstyle.jclife.utils;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;

import com.jstyle.jclife.R;
import com.jstyle.jclife.activity.HealthHistoryActivity;
import com.jstyle.jclife.model.HealthData;

import java.io.UnsupportedEncodingException;
import java.text.NumberFormat;

public class ResolveData {
    private static final int SHORTENED_LOCAL_NAME = 0x08;
    private static final int COMPLETE_LOCAL_NAME = 0x09;

    public static String decodeDeviceName(BluetoothDevice bluetoothDevice,byte[] data) {
        String name = bluetoothDevice.getName();
        if(!TextUtils.isEmpty(name))return name;
        int fieldLength, fieldName;
        int packetLength = data.length;
        for (int index = 0; index < packetLength; index++) {
            fieldLength = data[index];
            if (fieldLength == 0)
                break;
            fieldName = data[++index];
            if (fieldName == COMPLETE_LOCAL_NAME
                    || fieldName == SHORTENED_LOCAL_NAME) {
                name = decodeLocalName(data, index + 1, fieldLength - 1);
                break;
            }
            index += fieldLength - 1;
        }
        return name;
    }

    /**
     * Decodes the local name
     */
    public static String decodeLocalName(final byte[] data, final int start,
                                         final int length) {
        try {
            return new String(data, start, length, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            Log.e("scan", "Unable to convert the complete local name to UTF-8",
                    e);
            return null;
        } catch (final IndexOutOfBoundsException e) {
            Log.e("scan", "Error when reading complete local name", e);
            return null;
        }
    }

    /**
     * 转十六进制字符串
     *
     * @param data
     * @return
     */
    public static String byte2Hex(byte[] data) {
        if (data != null && data.length > 0) {
            StringBuilder sb = new StringBuilder(data.length);
            for (byte tmp : data) {
                sb.append(String.format("%02X ", tmp));
            }
            return sb.toString();
        }
        return "no data";
    }

    public static int getSleepQualityLevel(float deepSleepTime, float lightSleepTime) {
        int level = 0;
        float totalTime = deepSleepTime + lightSleepTime;
        if ((totalTime > 450 && totalTime < 540) && (deepSleepTime > 90 && deepSleepTime < 210) && (lightSleepTime > 210 && lightSleepTime < 360)) {
            level = 4;
        } else if (deepSleepTime + lightSleepTime > 360) {
            level = 3;
        } else if (deepSleepTime + lightSleepTime > 270) {
            level = 2;
        } else if (deepSleepTime + lightSleepTime > 0 && deepSleepTime + lightSleepTime <= 270) {
            level = 1;
        } else if (deepSleepTime + lightSleepTime == 0) {
            level = 0;
        }
        return level;
    }

    public static int getSleepLevel(int data) {
        int level = 0;
        if (data >= 0 && data <= 8) {//深睡
            level = 0;
        } else if (data > 8 && data <= 40) {//浅睡
            level = 1;
        } else if (data > 40) {//清醒
            level = 2;
        }
        return level;
    }

    public static int getHeartRange(float heartRateV, int MHR) {
        int range = -1;
        float heartRate = heartRateV;
        if (heartRate >= 0.5f * MHR && heartRate <= 0.6f * MHR) {//热身
            range = 0;
        } else if (heartRate >= 0.6f * MHR && heartRate < 0.7f * MHR) {//燃脂
            range = 1;
        } else if (heartRate >= 0.7f * MHR && heartRate < 0.8f * MHR) {//有氧
            range = 2;
        } else if (heartRate >= 0.8f * MHR && heartRate < 0.9f * MHR) {//肌力
            range = 3;
        } else if (heartRate >= 0.9f * MHR) {//无氧
            range = 4;
        }
        return range;
    }

    public static int getData(HealthData healthData, int dateType) {
        int data = 0;
        switch (dateType) {
            case HealthHistoryActivity.DATA_HRV:
                data = healthData.getHrv();
                break;
            case HealthHistoryActivity.DATA_BLOOD:
                data = healthData.getHighBloodPressure();
                break;
            case HealthHistoryActivity.DATA_PRESSURE:
                data = healthData.getPressure();
                break;

        }
        return data;
    }

    public static NumberFormat getNumberFormat(int max) {
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setMaximumFractionDigits(max);

        numberFormat.setGroupingUsed(false);
        return numberFormat;
    }

    public static void getBPStatus(int highBP, int lowBP, int[] statusArray) {
        if (highBP - lowBP > 80) statusArray[3]++;
        if (highBP >= 140 || lowBP >= 90) statusArray[2]++;
        if (highBP < 90 && lowBP <= 60) statusArray[1]++;
        if (highBP < 140 && lowBP > 60) statusArray[0]++;
    }

    private static final String TAG = "ResolveData";

    public static int CalcCRC16(byte[] pArray, int length) {
        int wCRC = 0xFFFF;
        int CRC_Count = length;
        int i;
        int num = 0;
        while (CRC_Count > 0) {
            CRC_Count--;
            wCRC = wCRC ^ (0xFF & pArray[num++]);
            for (i = 0; i < 8; i++) {
                if ((wCRC & 0x0001) == 1) {
                    wCRC = wCRC >> 1 ^ 0xA001;
                } else {
                    wCRC = wCRC >> 1;
                }
            }
        }
        return wCRC;
    }

    public static int  getHrvLevel(int hrv) {
        int level = 0;
        if (hrv > 0 && hrv < 26) {
            level = 3;
        } else if (hrv >= 26 && hrv < 37) {
            level = 2;
        } else if (hrv >= 37 && hrv < 55) {
            level = 1;
        } else if (hrv >= 55) {
            level = 0;
        }
        return  level;

    }
    public static int getStressLevel(int stress) {
        int level = 0;
        if (stress> 0 &&stress <= 25) {//平静
            level = 0;
        } else if (stress <=50) {//舒缓
            level = 1;
        } else if (stress<= 75) {//紧张
            level = 2;
        } else if (stress >75) {//焦虑
            level = 3;
        }
        return level;
    }
    public  static String getLastDataString(HealthData lastHealthData,int dataType){
        String lastText="";
        if(dataType==HealthHistoryActivity.DATA_BLOOD){
            String highLast = lastHealthData.getHighBloodPressure() == 0 ? "--" : String.valueOf(lastHealthData.getHighBloodPressure());
            String lowLast = lastHealthData.getLowBloodPressure() == 0 ? "--" : String.valueOf(lastHealthData.getLowBloodPressure());
            lastText = highLast + "/" + lowLast + "\nmmHg";
        }else if(dataType==HealthHistoryActivity.DATA_HRV){
            lastText=String.valueOf(lastHealthData.getHrv());
        }else  if(dataType==HealthHistoryActivity.DATA_PRESSURE){
            lastText=String.valueOf(lastHealthData.getPressure());
        }
        return lastText;
    }

    public static String getShowDistance(String distance){
        NumberFormat numberFormat=getNumberFormat(2);
        distance=distance.replace(",",".");
        float distanceKm=Float.valueOf(distance);
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        String showDistance=enable_DistanceUnit?numberFormat.format(distanceKm*0.621f):numberFormat.format(distanceKm);
        return showDistance.replace(",",".");
    }
    public static String getDistanceLabel(){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?" mile":" km";
    }
    public static String getHomeDistanceLabel(){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?"mile":"km";
    }

    public static String getDistanceLabel(Context context){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?context.getString(R.string.distance_unit_mile):context.getString(R.string.distance_unir);
    }
    public static String getSpeedLabel(Context context){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?context.getString(R.string.Average_speed_mile):context.getString(R.string.Average_speed);
    }
    public static String getPaceLabel(Context context){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?context.getString(R.string.Average_pace_mile):context.getString(R.string.Average_pace);
    }

    /**分享界面
     * @param context
     * @return
     */
    public static String getSharePaceLabel(Context context){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?context.getString(R.string.share_pace_format_mile):context.getString(R.string.share_pace_format);
    }
    public static String getDetailPaceLabel(Context context,String pace){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?String.format(context.getString(R.string.avg_pace_format_mile),pace):String.format(context.getString(R.string.avg_pace_format),pace);
    }
    public static String getShowPace(Context context,String pace){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        if(pace.contains("'")){
            String min=pace.split("'")[0];
            String second=pace.split("'")[1].split("\"")[0];
            int speedSeconds= Integer.valueOf(min)*60+Integer.valueOf(second);
            int speedSecondMile= (int) (speedSeconds*1.6093f);
            return enable_DistanceUnit?DateUtil.getPaceTime(speedSecondMile):pace;
        }else{
//            int speedSeconds= Integer.valueOf(min)*60+Integer.valueOf(second);
//            int speedSecondMile= (int) (speedSeconds*1.6093f);
            return enable_DistanceUnit?DateUtil.getPaceTime(0):DateUtil.getPaceTime(0);

        }

    }
    public static String getDetailDistanceLabel(Context context){
        boolean enable_DistanceUnit = SharedPreferenceUtils.getBoolean(GlobalConst.KEY_DistanceUnit, false);
        return enable_DistanceUnit?context.getString(R.string.Mile):context.getString(R.string.Kilometre);
    }

    public static String getPeople(String mNumber, Context context) {
        String name = "";
        if (context == null) return mNumber;
        Uri uriNumber2Contacts = Uri.parse("content://com.android.contacts/"
                + "data/phones/filter/" + mNumber);
        Cursor cursor = context.getContentResolver().query(
                uriNumber2Contacts,
                null,
                null, null, null);
        if (cursor == null) {
            return mNumber;
        }
        if( cursor.getCount()>0) {
            cursor.moveToFirst();
            int nameFieldColumnIndex = cursor
                    .getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME);
            cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME);
            name = cursor.getString(nameFieldColumnIndex);
        }
        if (cursor != null) {
            cursor.close();
        }

        return TextUtils.isEmpty(name)?mNumber:name;
    }
    static double[] b = new double[]{0.054739922017691    ,     -0.212533392978115,  0.315586949528711   ,     -0.212533392978115
            ,0.054739922017691};
    static double[] a = new double[]{1.0000      ,     -3.886147986061713          ,         5.665605879501376    ,
            -3.672727147512168            ,           0.893269389361558 };

    public static Double[] getSleepQData(Double[] source) {

        int length=source.length;
      //  double[] firstDatas = new double[length];
        double[] secDatas = new double[length];
        Double[] thirdDatas = new Double[length];
        for(int i=0;i<length;i++){
            source[i]=source[i]*18.3/128;
        }
        for (int i = 11; i < length; i++) {
            double total=0;
            for(int j=0;j<12;j++){
                total+=source[i-j];
            }
            source[i] = total/12;
        }
//        source[0] = (source[0] + source[1] + source[2]) / 3f;
//        source[1] = (source[0] + source[1] + source[2] + source[3]) / 4f;
//        source[length-2] = (source[length-4] + source[length-3] + source[length-2] + source[length-1]) / 4f;
//        source[length-1] = (source[length-3] + source[length-2] + source[length-1]) / 3f;
        for (int i = 4; i < length-4; i++) {
            secDatas[i] = b[0] * source[i] +
                    b[1]* source[i - 1] +
                    b[2] * source[i - 2] +
                    b[3]* source[i -3] +
                    b[4] * source[i - 4] -
                    a[1] * secDatas[i - 1] -
                    a[2] * secDatas[i - 2] -
                    a[3] * secDatas[i - 3] -
                    a[4] * secDatas[i - 4] ;
            //thirdDatas[i - 4] = -secDatas[i];
        }
        for(int i=11;i<length;i++){
            double total=0;
            for(int j=0;j<12;j++){
                total+=secDatas[i-j];
            }
            thirdDatas[i]=-total/12*2;
            if(thirdDatas[i]<0)thirdDatas[i]=thirdDatas[i]/2;
        }
//        thirdDatas[length-4] = -secDatas[length-1];
//        thirdDatas[length-3] = -secDatas[length-1];
//        thirdDatas[length-2] = -secDatas[length-1];
//        thirdDatas[length-1] = -secDatas[length-1];
        return thirdDatas;
    }
    final static int maxSize=5;
    static double[] tmp_x = new double[maxSize];
    static double[] tmp_y = new double[maxSize];
    public static double getSleepQData(double dat) {
        for (int i = maxSize-1; i > 0; i--) {
            tmp_x[i] = tmp_x[i - 1];
            tmp_y[i] = tmp_y[i - 1];
        }
        tmp_x[0]=dat*18.3/128;
        double totalX=0;
        for(int i=0;i<maxSize;i++){
           totalX+=tmp_x[i];
        }
        tmp_x[0] =totalX/maxSize ;
        tmp_y[0]  = b[0] * tmp_x[0] +
                    b[1]* tmp_x[1] +
                    b[2] * tmp_x[2] +
                    b[3]* tmp_x[3] +
                    b[4] * tmp_x[4] -
                    a[1] * tmp_y[1] -
                    a[2] * tmp_y[2] -
                    a[3] * tmp_y[3] -
                    a[4] * tmp_y[4] ;
        double totalY=0;
        for(int i=0;i<maxSize;i++){
            totalY+=tmp_y[i];
        }
        totalY=-totalY/maxSize*2;
        if(totalY<0) totalY= totalY/2.5;
        if(totalY>800)totalY=800;
        if(totalY<-400)totalY=-400;
        Log.i(TAG, "getSleepQData: "+totalY);
        return totalY ;
    }

}